cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

# 定义项目名称和使用的语言。
project(recipe-22 LANGUAGES CXX)

# 强制使用 C++11 标准。
# CMAKE_CXX_EXTENSIONS OFF 禁用 GNU 扩展，确保代码更具可移植性。
# CMAKE_CXX_STANDARD_REQUIRED ON 确保编译器必须支持指定的 C++ 标准。
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# ----------------------------------------------------------------------------
# 1. 构建求和函数库
# ----------------------------------------------------------------------------
# 添加一个名为 'sum_integers' 的库，由 sum_integers.cpp 源文件构建。
# 默认情况下，CMake 会创建静态库。
add_library(sum_integers sum_integers.cpp)

# ----------------------------------------------------------------------------
# 2. 构建主程序可执行文件 (sum_up)
# ----------------------------------------------------------------------------
# 添加一个名为 'sum_up' 的可执行文件，由 main.cpp 源文件构建。
add_executable(sum_up main.cpp)

# 将 'sum_up' 可执行文件链接到 'sum_integers' 库。
# 这意味着 sum_up 将能够调用 sum_integers 库中定义的函数。
target_link_libraries(sum_up sum_integers)

# ----------------------------------------------------------------------------
# 3. 集成 Boost.Test 单元测试
# ----------------------------------------------------------------------------
# 查找 Boost 库。
# REQUIRED 表示如果找不到 Boost 库，配置将失败。
# COMPONENTS unit_test_framework 指定我们需要 Boost.Test 框架组件。
# CMake 会设置 Boost_INCLUDE_DIRS 和 Boost_UNIT_TEST_FRAMEWORK_LIBRARY 等变量，
# 或者更现代地，提供 Boost::unit_test_framework 这样的IMPORTED目标。
find_package(Boost 1.54 REQUIRED COMPONENTS unit_test_framework)

# 添加一个名为 'cpp_test' 的可执行文件，由 test.cpp 源文件构建。
# 这个可执行文件将包含我们的所有单元测试。
add_executable(cpp_test test.cpp)

# 将 'cpp_test' 可执行文件链接到所需的库。
target_link_libraries(cpp_test
  PRIVATE # PRIVATE 关键字表示这些链接依赖只对 'cpp_test' 目标自身可见，不传递给依赖 'cpp_test' 的其他目标。
    sum_integers               # 链接我们自定义的求和库
    Boost::unit_test_framework # 链接 Boost.Test 框架库。这是 CMake find_package 提供的现代方式。
)

# 定义编译宏。
# BOOST_TEST_DYN_LINK 宏告诉 Boost.Test 库我们正在动态链接它。
# 这对于正确解析符号是必要的，特别是当 Boost.Test 作为共享库构建时。
# 注意：这个宏与 Boost.Test 自动生成 main 函数无关，main 函数由 BOOST_TEST_MODULE 宏负责。
target_compile_definitions(cpp_test
  PRIVATE
      BOOST_TEST_DYN_LINK
)

# ----------------------------------------------------------------------------
# 4. 配置 CTest (CMake 的测试驱动程序)
# ----------------------------------------------------------------------------
# 启用 CTest 支持。这使得 'ctest' 命令可以发现并运行项目中定义的测试。
enable_testing()

# 定义一个测试，使其可以被 CTest 发现和运行。
# NAME: 测试的名称，将显示在 CTest 报告中。
# COMMAND: 运行测试时执行的命令。$<TARGET_FILE:cpp_test> 会解析为 'cpp_test' 可执行文件的完整路径。
add_test(
  NAME boost_test
  COMMAND $<TARGET_FILE:cpp_test>
)